#include "lightPost.h"
#include <math.h>

GLuint lightPost::_textureId = 0;

const float ALPHA = 1.0f; //The opacity of each face of the cube

//shiny (metallic) material property for light posts
GLfloat lightPost_shininess[] = {0.20, 0.20, 0.20, 1.0 };

lightPost::lightPost(int rot, GLfloat posX, GLfloat posY, GLfloat posZ)
{
	// memebers
	this->light = new spotLight();
	this->posX = posX;
	this->posY = posY;
	this->posZ = posZ;

	rectHeight = 0.3;
	rectWidth = 0.9;
	lightHeight = 0.2;
	lightWidth = 0.2;
	cylHeight = 5.7;
	cylRadius = 0.1;

	//default lamp rectanlge inclination (45 degrees downwards)
	rotationLight1 = -45;
	quad = gluNewQuadric();

	// values that help the creation of ligths
	GLfloat lightPostHeight = 6;
	GLfloat sideValue = lightPostHeight * (sqrt(2.0f)/2);
	GLfloat spotLightDirY = -lightPostHeight/1.3;

	//rotation/position of lamp post and its properties depending on position on map
	if(rot == 1)  // North West
	{
		rotationLight = -45;
		this->posX += 0;
		this->posY += 0;
		this->posZ += 0;
		
		// setup the light
		this->light->setPosition(posX, lightPostHeight, posZ);
		this->light->setDirection(sideValue, spotLightDirY, sideValue);

		// setup the camera
		this->cam = new cugl::Camera(cugl::Point(posX+0.25, lightPostHeight, posZ+0.25), cugl::Point(sideValue, 0, sideValue), cugl::Vector(1, 1, 1).unit());
	}
	else if(rot == 2) // North East
	{
		rotationLight = -135;
		this->posX += -0.2;
		this->posY += 0;
		this->posZ += 0;

		// setup the light
		this->light->setPosition(posX, lightPostHeight, posZ);
		this->light->setDirection(-sideValue, spotLightDirY, sideValue);

		// setup the camera
		this->cam = new cugl::Camera(cugl::Point(posX-0.25, lightPostHeight, posZ+0.25), cugl::Point(posX-sideValue, 0, sideValue), cugl::Vector(-1, 1, 1).unit());
	
	}
	else if (rot == 3)	// South West
	{
		rotationLight = 45;
		this->posX += 0;
		this->posY += 0;
		this->posZ += -0.2;

		// setup the light
		this->light->setPosition(posX, lightPostHeight, posZ);
		this->light->setDirection(sideValue, spotLightDirY, -sideValue);

		// setup the camera
		this->cam = new cugl::Camera(cugl::Point(posX+0.25, lightPostHeight, posZ-0.25), cugl::Point(sideValue, 0, posZ-sideValue), cugl::Vector(1, 1, -1).unit());
	}
	else if (rot == 4)	// South East
	{
		rotationLight = 135;
		this->posX += -0.2;
		this->posY += 0;
		this->posZ += -0.2;

		// setup the light
		this->light->setPosition(posX, lightPostHeight, posZ);
		this->light->setDirection(-sideValue, spotLightDirY, -sideValue);

		// setup the camera
		this->cam = new cugl::Camera(cugl::Point(posX-0.25, lightPostHeight, posZ-0.25), cugl::Point(posX-sideValue, 0, posZ-sideValue), cugl::Vector(-1, 1, -1).unit());
	}
	
	//load the images to use as textures
	if(lightPost::_textureId == 0)
	{
		Image* image = loadBMP("textures\\lightmetal.bmp");
		lightPost::_textureId = loadTexture(image);
		delete image;
	}
}

// turn ON this post's light
void lightPost::turnOn()
{
	this->light->turnOn();
}

cugl::Camera* lightPost::getCam()
{
	return this->cam;
}

// turn OFF this post's light
void lightPost::turnOff()
{
	this->light->turnOff();
}

//----------------------
// get light positions
GLfloat lightPost::getLightXPos()
{
	return this->light->getXPos();
}

GLfloat lightPost::getLightYPos()
{
	return this->light->getYPos();
}

GLfloat lightPost::getLightZPos()
{
	return this->light->getZPos();
}
//-------------------------

//-------------------------
// get light direction
//-------------------------
GLfloat lightPost::getLightXDir()
{
	return this->light->getXDir();
}

GLfloat lightPost::getLightYDir()
{
	return this->light->getYDir();
}

GLfloat lightPost::getLightZDir()
{
	return this->light->getZDir();
}
//-------------------------

void lightPost::display()
{	
	// load texture
	//create the texture, set to 'light metal' and wrap around the cylinder
	glBindTexture(GL_TEXTURE_2D, lightPost::_textureId);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glPushMatrix();
		glColor3f(0.3, 0.3,0.3);
		glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f);
		//lamp post
		glTranslatef(posX, posY, posZ);
		glTranslatef(0.1, 0, 0.1);
		glRotatef(rotationLight, 0, 1, 0);
		glPushMatrix();
			//gluQuadricDrawStyle(quad, GLU_FILL);
			gluQuadricNormals(quad, GLU_SMOOTH);
			gluQuadricTexture(quad, GL_TRUE);		//enable texture coordinates
			glRotatef(-90, 1, 0, 0);
			glNormal3f(0.0, 0.0, -1.0);
			gluCylinder(quad, cylRadius, cylRadius, cylHeight, 30, 3);
		glPopMatrix();

		glDisable(GL_CULL_FACE);
		glPushMatrix();
			//rectangle
			glTranslatef(0.15, cylHeight, 0.0);
			glRotatef(rotationLight1, 0, 0, 1);
			glNormal3f(1.0, 1.0, 1.0);
			glBegin(GL_QUADS);
				glVertex3f(0.0, -rectHeight/2, -rectWidth/2);
				glVertex3f(0.0, rectHeight/2, -rectWidth/2);
				glVertex3f(0.0, rectHeight/2, rectWidth/2);
				glVertex3f(0.0, -rectHeight/2, rectWidth/2);
			glEnd();
		
			
			//glDisable(GL_TEXTURE_2D);

			float lightSpace = 0.05;
			//loop of 3 white square lights on the rectangle
			for(int i = 0; i != 3; ++i)
			{
				glPushMatrix();
					glTranslatef(0.01, 0, -((lightWidth + lightSpace)*i));
					glTranslatef(0, -0.01, rectWidth/3.5);
					glNormal3f(1.0, -1.0, 1.0);
					glBegin(GL_QUADS);
						glColor3f(1.0, 1.0, 1.0);
						glVertex3f(0.0, -lightHeight/2, -lightWidth/2);
						glVertex3f(0.0, lightHeight/2, -lightWidth/2);
						glVertex3f(0.0, lightHeight/2, lightWidth/2);
						glVertex3f(0.0, -lightHeight/2, lightWidth/2);
					glEnd();
				glPopMatrix();
			}
		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);
			//glEnable(GL_TEXTURE_2D);
		glPopMatrix();
	glPopMatrix();
}

lightPost::~lightPost(void) 
{
	delete light;
	delete cam;
}
